/*
 * @Author: jiaqiang.li
 * @Date: 2022-06-17 13:30:15
 * @LastEditTime: 2022-06-27 18:40:45
 * @Description: file content
 */
#include "app_task.h"
#include "FreeRTOS.h"
#include "uart_driver.h"
#include "gpio_driver.h"
#include "spi_driver.h"
#include "adc_driver.h"
#include "cmsis_os.h"
#include "dma_driver.h"
#include "flash_driver.h"
#include "tr_driver.h"
#include "string.h"
#include "sys_task_base.h"
#include "bsp_init.h"
#include "main.h"
#include "vitalSignsAlgorithm.h"

/* Definitions for ethernetTask */
osThreadId_t appTaskHandle;
extern osMessageQueueId_t osMessageQueueId;
extern SPI_HandleTypeDef hspi1;
extern ADC_HandleTypeDef hadc1;
extern ADC_HandleTypeDef hadc3;


#define SAMPLING_NUMBER_256 256
#define SPI_TX_DATA_SIZE (5 + SAMPLING_NUMBER_256) //ADC1 or ADC3
#define SPI_DATA_HEAD 0xAAFF
#define SPI_DATA_TAIL 0xFFAA
#define ADC_ID_1 1
#define ADC_ID_3 3


__attribute__((section(".SRAM_D1"))) __IO uint16_t spi_TxTempData[SPI_TX_DATA_SIZE];
__attribute__((section(".SRAM_D1"))) __IO uint16_t ADC1_ConvertedValue[SAMPLING_NUMBER_256];
__attribute__((section(".SRAM_D1"))) __IO uint16_t ADC3_ConvertedValue[SAMPLING_NUMBER_256];


__IO uint16_t g_chirp_id = 0;
__IO uint8_t g_adc_covcpltflag = 0;
static uint16_t stop_tr_value = 0x0F83;
extern uint8_t SPI1_SEND_RECV_DATA;
extern uint8_t g_adc_data_selected;
extern osSemaphoreId_t mcOsSemaphoreId;




void adc_start(void)
{
	if(g_adc_data_selected == 0)
	{
		HAL_ADC_Start_DMA(&hadc1, (uint32_t *)&ADC1_ConvertedValue[0], SAMPLING_NUMBER_256);
    HAL_ADC_Start_DMA(&hadc3, (uint32_t *)&ADC3_ConvertedValue[0], SAMPLING_NUMBER_256);
	}
	else if(g_adc_data_selected == 1)
	{
		HAL_ADC_Start_DMA(&hadc1, (uint32_t *)&ADC1_ConvertedValue[0], SAMPLING_NUMBER_256);
	}
	else if(g_adc_data_selected == 3)
	{
		HAL_ADC_Start_DMA(&hadc3, (uint32_t *)&ADC3_ConvertedValue[0], SAMPLING_NUMBER_256);
	}

}

void adc_stop(void)
{
	if(g_adc_data_selected == 0)
	{
		HAL_ADC_Stop_DMA(&hadc1);
    HAL_ADC_Stop_DMA(&hadc3);
	}
	else if(g_adc_data_selected == 1)
	{
		HAL_ADC_Stop_DMA(&hadc1);
	}
	else if(g_adc_data_selected == 3)
	{
		HAL_ADC_Stop_DMA(&hadc3);
	}
    
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *AdcHandle)
{
		uint16_t spi_tx_offset = 0;
		uint16_t chirps = 0;
    HAL_ADC_Stop_DMA(AdcHandle);
    SCB_CleanInvalidateDCache();
    if (AdcHandle->Instance == ADC1)
    {
        g_adc_covcpltflag = (g_adc_covcpltflag | 0x01);
    }
    else if (AdcHandle->Instance == ADC3)
    {
        g_adc_covcpltflag = (g_adc_covcpltflag | 0x04);
		}
    if (g_adc_covcpltflag == 0x05 || (g_adc_data_selected != 0))
    {
				g_adc_covcpltflag = 0;

				if(g_adc_data_selected == 0)
				{
					SCB_CleanInvalidateDCache_by_Addr((uint32_t *)ADC1_ConvertedValue, (sizeof(uint16_t) * SAMPLING_NUMBER_256));
					SCB_CleanInvalidateDCache_by_Addr((uint32_t *)ADC3_ConvertedValue, (sizeof(uint16_t) * SAMPLING_NUMBER_256));
					adcDataSelector((uint16_t *)ADC1_ConvertedValue, (uint16_t *)ADC3_ConvertedValue, SAMPLING_NUMBER_256); //250us
				}
				else
				{
					if(g_adc_data_selected == 1)
					{
						chripTofft((uint16_t *)ADC1_ConvertedValue, SAMPLING_NUMBER);
						//copy adc1 data to spi buf send to pc
						SCB_CleanInvalidateDCache_by_Addr((uint32_t *)ADC1_ConvertedValue, (sizeof(uint16_t) * SAMPLING_NUMBER_256));
						spi_TxTempData[spi_tx_offset++] = SPI_DATA_HEAD;
						spi_TxTempData[spi_tx_offset++] = SAMPLING_NUMBER_256;
						spi_TxTempData[spi_tx_offset++] = ADC_ID_1;
						spi_TxTempData[spi_tx_offset++] = g_chirp_id & 0xFFFF;
						memcpy((uint8_t *)&spi_TxTempData[spi_tx_offset], (uint8_t *)ADC1_ConvertedValue, sizeof(uint16_t) * SAMPLING_NUMBER_256);
						spi_tx_offset += SAMPLING_NUMBER_256;
						spi_TxTempData[spi_tx_offset] = SPI_DATA_TAIL;
						HAL_SPI_Transmit_DMA(&hspi1, (uint8_t *)&spi_TxTempData, sizeof(spi_TxTempData));
					}	
					else if(g_adc_data_selected == 3)
					{
						chripTofft((uint16_t *)ADC3_ConvertedValue, SAMPLING_NUMBER);
						//copy adc3 data to spi buf send to pc
						SCB_CleanInvalidateDCache_by_Addr((uint32_t *)ADC3_ConvertedValue, (sizeof(uint16_t) * SAMPLING_NUMBER_256));
						spi_TxTempData[spi_tx_offset++] = SPI_DATA_HEAD;
						spi_TxTempData[spi_tx_offset++] = SAMPLING_NUMBER_256;
						spi_TxTempData[spi_tx_offset++] = ADC_ID_3;
						spi_TxTempData[spi_tx_offset++] = g_chirp_id & 0xFFFF;
						memcpy((uint8_t *)&spi_TxTempData[spi_tx_offset], (uint8_t *)ADC3_ConvertedValue, sizeof(uint16_t) * SAMPLING_NUMBER_256);
						spi_tx_offset += SAMPLING_NUMBER_256;
						spi_TxTempData[spi_tx_offset] = SPI_DATA_TAIL;	
						HAL_SPI_Transmit_DMA(&hspi1, (uint8_t *)&spi_TxTempData, sizeof(spi_TxTempData));						
					}
					SCB_CleanInvalidateDCache_by_Addr((uint32_t *)spi_TxTempData, sizeof(spi_TxTempData));
				}

				SCB_CleanInvalidateDCache();
				if(g_adc_data_selected == 0)
				{
					HAL_ADC_Start_DMA(&hadc1, (uint32_t *)ADC1_ConvertedValue, SAMPLING_NUMBER_256);
					HAL_ADC_Start_DMA(&hadc3, (uint32_t *)ADC3_ConvertedValue, SAMPLING_NUMBER_256);
				}
				else if(g_adc_data_selected == 1)
				{			
					HAL_ADC_Start_DMA(&hadc1, (uint32_t *)ADC1_ConvertedValue, SAMPLING_NUMBER_256);
				}
				else if(g_adc_data_selected == 3)
				{		
					HAL_ADC_Start_DMA(&hadc3, (uint32_t *)ADC3_ConvertedValue, SAMPLING_NUMBER_256);
				}
				g_chirp_id = (g_chirp_id + 1) % 0xffff;
				// reset clock
				TR_PosFlagClockReset();
    }
}

void app_task(void *param)
{
		ssMsg_t Msg;
    osStatus_t osState;
		TickType_t xMaxBlockTime = pdMS_TO_TICKS(500);

    for (;;)
     {
			 osState = osMessageQueueGet(osMessageQueueId, (void *)&Msg, 0, (TickType_t)xMaxBlockTime);
        if(osState == osOK)
				{
					switch (Msg.type)
					{
						case SS_MSG_CHRIPS_ENOUGH:
						{
							printf("SS_MSG_CHRIPS_ENOUGH\n");
							break;
						}
						case SS_MSG_UART4_RECV:
							{
								if(memcmp(Msg.data, "start", Msg.length) == 0)
								{
									if(SPI1_SEND_RECV_DATA != 1)
									{
										SPI1_SEND_RECV_DATA = 1;
										HAL_SPI_DeInit(&hspi1);
										osDelay(200);
										spi1_init();
									}

									adc_start();
									printf("start\r\n");
									break;
								}
								else if(memcmp(Msg.data, "stop", Msg.length)== 0)
								{
									adc_stop();
									ADC_Disable(&hadc1);
									ADC_Disable(&hadc3);
									TR_Write_Reg(0x00, 1, &stop_tr_value);
									printf("stop\r\n");
									break;
								}
								else if(memcmp(Msg.data, "gruArray", Msg.length) == 0)
								{
										setStartGruArrayTrans(TRUE);
										break;
								}
								else if(memcmp(Msg.data, "tasks", Msg.length) == 0)
								{
									get_task_state(0, NULL);
									break;
								}
								break;
							}
							default:
									break;
					}
					osSemaphoreRelease(mcOsSemaphoreId);
				}		
    }
}

void app_peripherals_init(void)
{
		base_task_init();
    dma_init();
    uart_init();
    spi2_init();
    spi1_init();
    osDelay(500);
    tr_init();
    adc_init();
    SCB_CleanInvalidateDCache();
}
const osThreadAttr_t appTaskAttr={
	.name = "appTask",
	.stack_size = 1024,
	.priority = osPriorityNormal,
	
};

void app_task_init(void)
{
	appTaskHandle = osThreadNew(app_task, NULL, &appTaskAttr);
	app_peripherals_init();
}